//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//

package org.apache.velocity.tools.view;

import org.apache.commons.collections.ExtendedProperties;
import org.apache.velocity.Template;
import org.apache.velocity.app.VelocityEngine;
import org.apache.velocity.context.Context;
import org.apache.velocity.exception.ResourceNotFoundException;
import org.apache.velocity.io.VelocityWriter;
import org.apache.velocity.tools.ToolboxFactory;
import org.apache.velocity.tools.config.ConfigurationCleaner;
import org.apache.velocity.tools.config.ConfigurationUtils;
import org.apache.velocity.tools.config.FactoryConfiguration;
import org.apache.velocity.tools.generic.log.LogChuteCommonsLog;
import org.apache.velocity.tools.view.context.ChainedContext;
import org.apache.velocity.util.SimplePool;

import javax.servlet.FilterConfig;
import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.io.Writer;
import java.util.List;

public class VelocityView extends ViewToolManager {
    public static final String CONTENT_TYPE_KEY = "default.contentType";
    public static final String SERVLET_CONTEXT_KEY = ServletContext.class.getName();
    public static final String DEFAULT_CONTENT_TYPE = "text/html";
    public static final String DEFAULT_OUTPUT_ENCODING = "ISO-8859-1";
    public static final String TOOLS_KEY = "org.apache.velocity.tools";
    /** @deprecated */
    @Deprecated
    public static final String DEPRECATED_TOOLS_KEY = "org.apache.velocity.toolbox";
    public static final String USER_TOOLS_PATH = "/WEB-INF/tools.xml";
    /** @deprecated */
    @Deprecated
    public static final String DEPRECATED_USER_TOOLS_PATH = "/WEB-INF/toolbox.xml";
    public static final String DEFAULT_PROPERTIES_PATH = "/org/apache/velocity/tools/view/velocity.properties";
    public static final String PROPERTIES_KEY = "org.apache.velocity.properties";
    public static final String USER_PROPERTIES_PATH = "/WEB-INF/velocity.properties";
    public static final String LOAD_DEFAULTS_KEY = "org.apache.velocity.tools.loadDefaults";
    public static final String CLEAN_CONFIGURATION_KEY = "org.apache.velocity.tools.cleanConfiguration";
    public static final String USER_OVERWRITE_KEY = "org.apache.velocity.tools.userCanOverwriteTools";
    public static final String DEPRECATION_SUPPORT_MODE_KEY = "org.apache.velocity.tools.deprecationSupportMode";
    private static SimplePool writerPool = new SimplePool(40);
    private String defaultContentType;
    private boolean deprecationSupportMode;

    public VelocityView(ServletConfig config) {
        this((JeeConfig)(new JeeServletConfig(config)));
    }

    public VelocityView(FilterConfig config) {
        this((JeeConfig)(new JeeFilterConfig(config)));
    }

    public VelocityView(ServletContext context) {
        this((JeeConfig)(new JeeContextConfig(context)));
    }

    public VelocityView(JeeConfig config) {
        super(config.getServletContext(), false, false);
        this.defaultContentType = "text/html";
        this.deprecationSupportMode = true;
        this.init(config);
    }

    /** @deprecated */
    @Deprecated
    protected final void setDeprecationSupportMode(boolean support) {
        if(this.deprecationSupportMode != support) {
            this.deprecationSupportMode = support;
            this.debug("deprecationSupportMode is now %s", new Object[]{support?"on":"off"});
        }

    }

    public void setVelocityEngine(VelocityEngine engine) {
        if(engine == null) {
            throw new NullPointerException("VelocityEngine cannot be null");
        } else {
            super.setVelocityEngine(engine);
        }
    }

    public String getDefaultContentType() {
        return this.defaultContentType;
    }

    public void setDefaultContentType(String type) {
        if(!this.defaultContentType.equals(type)) {
            this.defaultContentType = type;
            this.debug("Default Content-Type was changed to %s", new Object[]{type});
        }

    }

    protected String getProperty(String key, String alternate) {
        String prop = (String)this.velocity.getProperty(key);
        return prop != null && prop.length() != 0?prop:alternate;
    }

    protected void init(JeeConfig config) {
        if(this.velocity == null) {
            this.velocity = new VelocityEngine();
        }

        String depMode = config.findInitParameter("org.apache.velocity.tools.deprecationSupportMode");
        if(depMode != null && depMode.equalsIgnoreCase("false")) {
            this.setDeprecationSupportMode(false);
        }

        String allowOverwrite = config.findInitParameter("org.apache.velocity.tools.userCanOverwriteTools");
        if(allowOverwrite != null && allowOverwrite.equalsIgnoreCase("false")) {
            this.setUserCanOverwriteTools(false);
        }

        this.init(config, this.velocity);
        this.configure(config, this.factory);
        this.setEncoding(config);
    }

    protected void init(JeeConfig config, VelocityEngine velocity) {
        LogChuteCommonsLog.setVelocityLog(this.getLog());
        velocity.setApplicationAttribute(SERVLET_CONTEXT_KEY, this.servletContext);
        this.configure(config, velocity);

        try {
            velocity.init();
        } catch (Exception var5) {
            String msg = "Could not initialize VelocityEngine";
            this.getLog().error(msg, var5);
            var5.printStackTrace();
            throw new RuntimeException(msg + ": " + var5, var5);
        }
    }

    protected void configure(JeeConfig config, VelocityEngine velocity) {
        ExtendedProperties defaultProperties = this.getProperties("/org/apache/velocity/tools/view/velocity.properties", true);

        try {
            Class.forName("org.apache.velocity.tools.view.WebappUberspector");
        } catch (Throwable var6) {
            List servletPropsPath = defaultProperties.getList("runtime.introspector.uberspect");
            servletPropsPath.remove("org.apache.velocity.tools.view.WebappUberspector");
            defaultProperties.setProperty("runtime.introspector.uberspect", servletPropsPath);
        }

        velocity.setExtendedProperties(defaultProperties);
        String appPropsPath = this.servletContext.getInitParameter("org.apache.velocity.properties");
        this.setProps(velocity, appPropsPath, true);
        this.setProps(velocity, "/WEB-INF/velocity.properties", false);
        String servletPropsPath1 = config.getInitParameter("org.apache.velocity.properties");
        this.setProps(velocity, servletPropsPath1, true);
    }

    private boolean setProps(VelocityEngine velocity, String path, boolean require) {
        if(path == null) {
            return false;
        } else {
            ExtendedProperties props = this.getProperties(path, require);
            if(props == null) {
                return false;
            } else {
                this.debug("Configuring Velocity with properties at: %s", new Object[]{path});
                velocity.setExtendedProperties(props);
                return true;
            }
        }
    }

    protected void configure(JeeConfig config, ToolboxFactory factory) {
        FactoryConfiguration factoryConfig = new FactoryConfiguration("VelocityView.configure(config,factory)");
        boolean hasOldToolbox = false;
        if(this.deprecationSupportMode) {
            FactoryConfiguration loadDefaults = this.getDeprecatedConfig(config);
            if(loadDefaults != null) {
                hasOldToolbox = true;
                factoryConfig.addConfiguration(loadDefaults);
            }
        }

        String loadDefaults1 = config.findInitParameter("org.apache.velocity.tools.loadDefaults");
        if((hasOldToolbox || loadDefaults1 != null) && !"true".equalsIgnoreCase(loadDefaults1)) {
            this.debug("Default tools configuration has been suppressed%s", new Object[]{hasOldToolbox?" to avoid conflicts with older application\'s context and toolbox definition.":"."});
        } else {
            this.getLog().trace("Loading default tools configuration...");
            factoryConfig.addConfiguration(ConfigurationUtils.getDefaultTools());
        }

        FactoryConfiguration autoLoaded = ConfigurationUtils.getAutoLoaded(false);
        factoryConfig.addConfiguration(autoLoaded);
        String appToolsPath = this.servletContext.getInitParameter("org.apache.velocity.tools");
        this.setConfig(factoryConfig, appToolsPath, true);
        this.setConfig(factoryConfig, "/WEB-INF/tools.xml", false);
        String servletToolsPath = config.getInitParameter("org.apache.velocity.tools");
        this.setConfig(factoryConfig, servletToolsPath, true);
        FactoryConfiguration injected = ServletUtils.getConfiguration(this.servletContext);
        if(injected != null) {
            this.debug("Adding configuration instance in servletContext attributes as \'%s\'", new Object[]{"org.apache.velocity.tools"});
            factoryConfig.addConfiguration(injected);
        }

        String cleanConfig = config.findInitParameter("org.apache.velocity.tools.cleanConfiguration");
        if("true".equals(cleanConfig)) {
            ConfigurationCleaner cleaner = new ConfigurationCleaner();
            cleaner.setLog(this.getLog());
            cleaner.clean(factoryConfig);
        }

        this.debug("Configuring factory with: %s", new Object[]{factoryConfig});
        this.configure(factoryConfig);
    }

    /** @deprecated */
    @Deprecated
    protected FactoryConfiguration getDeprecatedConfig(JeeConfig config) {
        FactoryConfiguration toolbox = null;
        String oldPath = config.findInitParameter("org.apache.velocity.toolbox");
        if(oldPath != null) {
            toolbox = this.getConfiguration(oldPath, true);
        } else {
            oldPath = "/WEB-INF/toolbox.xml";
            toolbox = this.getConfiguration(oldPath);
        }

        if(toolbox != null) {
            this.debug("Loaded deprecated configuration from: %s", new Object[]{oldPath});
            this.getLog().warn("Please upgrade to new \"/WEB-INF/tools.xml\" format and conventional location. Support for \"/WEB-INF/toolbox.xml\" format and conventional file name will be removed in a future version.");
        }

        return toolbox;
    }

    private boolean setConfig(FactoryConfiguration factory, String path, boolean require) {
        if(path == null) {
            return false;
        } else {
            FactoryConfiguration config = this.getConfiguration(path, require);
            if(config == null) {
                return false;
            } else {
                this.debug("Loaded configuration from: %s", new Object[]{path});
                factory.addConfiguration(config);
                return true;
            }
        }
    }

    protected InputStream getInputStream(String path, boolean required) {
        InputStream inputStream = ServletUtils.getInputStream(path, this.servletContext);
        if(inputStream == null) {
            String msg = "Did not find resource at: " + path;
            if(required) {
                this.getLog().error(msg);
                throw new ResourceNotFoundException(msg);
            } else {
                this.debug(msg, new Object[0]);
                return null;
            }
        } else {
            return inputStream;
        }
    }

    protected ExtendedProperties getProperties(String path) {
        return this.getProperties(path, false);
    }

    protected ExtendedProperties getProperties(String path, boolean required) {
        if(this.getLog().isTraceEnabled()) {
            this.getLog().trace("Searching for properties at: " + path);
        }

        InputStream inputStream = this.getInputStream(path, required);
        if(inputStream == null) {
            return null;
        } else {
            ExtendedProperties properties = new ExtendedProperties();

            try {
                properties.load(inputStream);
            } catch (IOException var15) {
                String msg = "Failed to load properties at: " + path;
                this.getLog().error(msg, var15);
                if(required) {
                    throw new RuntimeException(msg, var15);
                }
            } finally {
                try {
                    if(inputStream != null) {
                        inputStream.close();
                    }
                } catch (IOException var14) {
                    this.getLog().error("Failed to close input stream for " + path, var14);
                }

            }

            return properties;
        }
    }

    protected FactoryConfiguration getConfiguration(String path) {
        return this.getConfiguration(path, false);
    }

    protected FactoryConfiguration getConfiguration(String path, boolean required) {
        if(this.getLog().isTraceEnabled()) {
            this.getLog().trace("Searching for configuration at: " + path);
        }

        FactoryConfiguration config = null;

        try {
            config = ServletUtils.getConfiguration(path, this.servletContext, this.deprecationSupportMode);
            if(config == null) {
                String re = "Did not find resource at: " + path;
                if(required) {
                    this.getLog().error(re);
                    throw new ResourceNotFoundException(re);
                }

                this.debug(re, new Object[0]);
            }
        } catch (ResourceNotFoundException var5) {
            throw var5;
        } catch (RuntimeException var6) {
            if(required) {
                this.getLog().error(var6.getMessage(), var6);
                throw var6;
            }

            this.getLog().debug(var6.getMessage(), var6);
        }

        return config;
    }

    protected void setEncoding(JeeConfig config) {
        this.defaultContentType = this.getProperty("default.contentType", "text/html");
        String encoding = this.getProperty("output.encoding", "ISO-8859-1");
        if(!"ISO-8859-1".equalsIgnoreCase(encoding)) {
            int index = this.defaultContentType.lastIndexOf("charset");
            if(index < 0) {
                this.defaultContentType = this.defaultContentType + "; charset=" + encoding;
            } else {
                this.getLog().info("Charset was already specified in the Content-Type property.  Output encoding property will be ignored.");
            }
        }

        this.debug("Default Content-Type is: %s", new Object[]{this.defaultContentType});
    }

    public Context render(HttpServletRequest request, HttpServletResponse response) throws IOException {
        ViewToolContext context = this.createContext(request, response);
        Template template = this.getTemplate(request, response);
        this.merge(template, context, response.getWriter());
        return context;
    }

    public Context render(HttpServletRequest request, Writer out) throws IOException {
        ViewToolContext context = this.createContext(request, (HttpServletResponse)null);
        Template template = this.getTemplate(request);
        this.merge(template, context, out);
        return context;
    }

    public ViewToolContext createContext(HttpServletRequest request, HttpServletResponse response) {
        Object ctx;
        if(this.deprecationSupportMode) {
            ctx = new ChainedContext(this.velocity, request, response, this.servletContext);
        } else {
            ctx = new ViewToolContext(this.velocity, request, response, this.servletContext);
        }

        this.prepareContext((ViewToolContext)ctx, request);
        return (ViewToolContext)ctx;
    }

    public Template getTemplate(HttpServletRequest request) {
        return this.getTemplate((HttpServletRequest)request, (HttpServletResponse)null);
    }

    public Template getTemplate(HttpServletRequest request, HttpServletResponse response) {
        String path = ServletUtils.getPath(request);
        return response == null?this.getTemplate(path):this.getTemplate(path, response.getCharacterEncoding());
    }

    public Template getTemplate(String name) {
        return this.getTemplate((String)name, (String)null);
    }

    public Template getTemplate(String name, String encoding) {
        try {
            return encoding == null?this.velocity.getTemplate(name,"utf-8"):this.velocity.getTemplate(name, encoding);
        } catch (RuntimeException var4) {
            throw var4;
        } catch (Exception var5) {
            throw new RuntimeException(var5);
        }
    }

    public void merge(Template template, Context context, Writer writer) throws IOException {
        VelocityWriter vw = null;

        try {
            vw = (VelocityWriter)writerPool.get();
            if(vw == null) {
                vw = new VelocityWriter(writer, 4096, true);
            } else {
                vw.recycle(writer);
            }

            this.performMerge(template, context, vw);
            vw.flush();
        } finally {
            if(vw != null) {
                try {
                    vw.recycle((Writer)null);
                    writerPool.put(vw);
                } catch (Exception var11) {
                    this.getLog().error("Trouble releasing VelocityWriter: " + var11.getMessage(), var11);
                }
            }

        }

    }

    protected void performMerge(Template template, Context context, Writer writer) throws IOException {
        template.merge(context, writer);
    }
}
